package com.may.elasticsearch.bootstrap.service;

import cn.hutool.core.lang.Console;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.may.Content;
import com.may.utils.HtmlParseUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @program: dubbo-nacos
 * @description:
 * @author: Bobby.Ma
 * @create: 2020-07-08 22:17
 **/
@Slf4j
@Service
public class ContentService {

    @Resource
    private RestHighLevelClient restHighLevelClient;

    /**
        * @Description: 解析数据插入到 es 索引库中
        * @param keywords
        * @return: java.lang.Boolean
        * @Author: Bobby.Ma
        * @Date: 2020/7/8 22:19
    */
    public Boolean parseContent(String keywords) throws IOException {
        List<Content> contents = HtmlParseUtil.parseJDSearch(keywords);
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("2m");
        contents.forEach(content -> {
            bulkRequest.add(new IndexRequest("jd_goods").source(JSON.toJSONString(content), XContentType.JSON));
        });
        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return !bulk.hasFailures();
    }

    /**
        * @Description: es 搜索
        * @param keyword
        * @param page
        * @param pagesize
        * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
        * @Author: Bobby.Ma
        * @Date: 2020/7/8 22:47
    */
    public List<Map<String,Object>> searchPage(String keyword,int page,int pagesize) throws IOException {
        page = Math.max(page, 1);
        SearchRequest searchRequest = new SearchRequest("jd_goods");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder
                .timeout(new TimeValue(60, TimeUnit.SECONDS))
                .from(page).size(pagesize);
//                .sort("price", SortOrder.DESC);

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        //构建搜索条件
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", keyword);
        boolQuery.filter(queryBuilder);
        searchSourceBuilder.query(boolQuery);

        JSONObject jsonObject = JSONUtil.parseObj(searchSourceBuilder.toString());
        Console.log(jsonObject.toStringPretty());

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //解析高亮
        return Arrays.stream(searchResponse.getHits().getHits()).map(hit -> {
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField name = highlightFields.get("name");//高亮字段
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来结果
            if (name != null){
                StringBuilder newName = new StringBuilder();
                Arrays.stream(name.fragments()).forEach(newName::append);
                sourceAsMap.put("name",newName);//替换为高亮字段

            }
            return sourceAsMap;
        }).collect(Collectors.toList());
//        return Arrays.stream(searchResponse.getHits().getHits()).map(SearchHit::getSourceAsMap).collect(Collectors.toList());
    }
}
